//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2021 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto/tree/main/CodeGenerator. DO NOT EDIT.

import Foundation
import SotoCore

extension Transfer {
    // MARK: Enums

    public enum Domain: String, CustomStringConvertible, Codable {
        case efs = "EFS"
        case s3 = "S3"
        public var description: String { return self.rawValue }
    }

    public enum EndpointType: String, CustomStringConvertible, Codable {
        case `public` = "PUBLIC"
        case vpc = "VPC"
        case vpcEndpoint = "VPC_ENDPOINT"
        public var description: String { return self.rawValue }
    }

    public enum HomeDirectoryType: String, CustomStringConvertible, Codable {
        case logical = "LOGICAL"
        case path = "PATH"
        public var description: String { return self.rawValue }
    }

    public enum IdentityProviderType: String, CustomStringConvertible, Codable {
        case apiGateway = "API_GATEWAY"
        case serviceManaged = "SERVICE_MANAGED"
        public var description: String { return self.rawValue }
    }

    public enum `Protocol`: String, CustomStringConvertible, Codable {
        case ftp = "FTP"
        case ftps = "FTPS"
        case sftp = "SFTP"
        public var description: String { return self.rawValue }
    }

    public enum State: String, CustomStringConvertible, Codable {
        case offline = "OFFLINE"
        case online = "ONLINE"
        case startFailed = "START_FAILED"
        case starting = "STARTING"
        case stopFailed = "STOP_FAILED"
        case stopping = "STOPPING"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CreateServerRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the AWS Certificate Manager (ACM) certificate. Required when Protocols is set to FTPS. To request a new public certificate, see Request a public certificate in the  AWS Certificate Manager User Guide. To import an existing certificate into ACM, see Importing certificates into ACM in the  AWS Certificate Manager User Guide. To request a private certificate to use FTPS through private IP addresses, see Request a private certificate in the  AWS Certificate Manager User Guide. Certificates with the following cryptographic algorithms and key sizes are supported:   2048-bit RSA (RSA_2048)   4096-bit RSA (RSA_4096)   Elliptic Prime Curve 256 bit (EC_prime256v1)   Elliptic Prime Curve 384 bit (EC_secp384r1)   Elliptic Prime Curve 521 bit (EC_secp521r1)    The certificate must be a valid SSL/TLS X.509 version 3 certificate with FQDN or IP address specified and information about the issuer.
        public let certificate: String?
        public let domain: Domain?
        /// The virtual private cloud (VPC) endpoint settings that are configured for your server. When you host your endpoint within your VPC, you can make it accessible only to resources within your VPC, or you can attach Elastic IPs and make it accessible to clients over the internet. Your VPC's default security groups are automatically assigned to your endpoint.
        public let endpointDetails: EndpointDetails?
        /// The type of VPC endpoint that you want your server to connect to. You can choose to connect to the public internet or a VPC endpoint. With a VPC endpoint, you can restrict access to your server and resources only within your VPC.  It is recommended that you use VPC as the EndpointType. With this endpoint type, you have the option to directly associate up to three Elastic IPv4 addresses (BYO IP included) with your server's endpoint and use VPC security groups to restrict traffic by the client's public IP address. This is not possible with EndpointType set to VPC_ENDPOINT.
        public let endpointType: EndpointType?
        /// The RSA private key as generated by the ssh-keygen -N "" -m PEM -f my-new-server-key command.  If you aren't planning to migrate existing users from an existing SFTP-enabled server to a new server, don't update the host key. Accidentally changing a server's host key can be disruptive.  For more information, see Change the host key for your SFTP-enabled server in the AWS Transfer Family User Guide.
        public let hostKey: String?
        /// Required when IdentityProviderType is set to API_GATEWAY. Accepts an array containing all of the information required to call a customer-supplied authentication API, including the API Gateway URL. Not required when IdentityProviderType is set to SERVICE_MANAGED.
        public let identityProviderDetails: IdentityProviderDetails?
        /// Specifies the mode of authentication for a server. The default value is SERVICE_MANAGED, which allows you to store and access user credentials within the AWS Transfer Family service. Use the API_GATEWAY value to integrate with an identity provider of your choosing. The API_GATEWAY setting requires you to provide an API Gateway endpoint URL to call for authentication using the IdentityProviderDetails parameter.
        public let identityProviderType: IdentityProviderType?
        /// Allows the service to write your users' activity to your Amazon CloudWatch logs for monitoring and auditing purposes.
        public let loggingRole: String?
        /// Specifies the file transfer protocol or protocols over which your file transfer protocol client can connect to your server's endpoint. The available protocols are:    SFTP (Secure Shell (SSH) File Transfer Protocol): File transfer over SSH    FTPS (File Transfer Protocol Secure): File transfer with TLS encryption    FTP (File Transfer Protocol): Unencrypted file transfer    If you select FTPS, you must choose a certificate stored in AWS Certificate Manager (ACM) which will be used to identify your server when clients connect to it over FTPS. If Protocol includes either FTP or FTPS, then the EndpointType must be VPC and the IdentityProviderType must be API_GATEWAY. If Protocol includes FTP, then AddressAllocationIds cannot be associated. If Protocol is set only to SFTP, the EndpointType can be set to PUBLIC and the IdentityProviderType can be set to SERVICE_MANAGED.
        public let protocols: [Protocol]?
        /// Specifies the name of the security policy that is attached to the server.
        public let securityPolicyName: String?
        /// Key-value pairs that can be used to group and search for servers.
        public let tags: [Tag]?

        public init(certificate: String? = nil, domain: Domain? = nil, endpointDetails: EndpointDetails? = nil, endpointType: EndpointType? = nil, hostKey: String? = nil, identityProviderDetails: IdentityProviderDetails? = nil, identityProviderType: IdentityProviderType? = nil, loggingRole: String? = nil, protocols: [Protocol]? = nil, securityPolicyName: String? = nil, tags: [Tag]? = nil) {
            self.certificate = certificate
            self.domain = domain
            self.endpointDetails = endpointDetails
            self.endpointType = endpointType
            self.hostKey = hostKey
            self.identityProviderDetails = identityProviderDetails
            self.identityProviderType = identityProviderType
            self.loggingRole = loggingRole
            self.protocols = protocols
            self.securityPolicyName = securityPolicyName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.certificate, name: "certificate", parent: name, max: 1600)
            try self.endpointDetails?.validate(name: "\(name).endpointDetails")
            try self.validate(self.hostKey, name: "hostKey", parent: name, max: 4096)
            try self.identityProviderDetails?.validate(name: "\(name).identityProviderDetails")
            try self.validate(self.loggingRole, name: "loggingRole", parent: name, max: 2048)
            try self.validate(self.loggingRole, name: "loggingRole", parent: name, min: 20)
            try self.validate(self.loggingRole, name: "loggingRole", parent: name, pattern: "arn:.*role/.*")
            try self.validate(self.protocols, name: "protocols", parent: name, max: 3)
            try self.validate(self.protocols, name: "protocols", parent: name, min: 1)
            try self.validate(self.securityPolicyName, name: "securityPolicyName", parent: name, max: 100)
            try self.validate(self.securityPolicyName, name: "securityPolicyName", parent: name, pattern: "TransferSecurityPolicy-.+")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case certificate = "Certificate"
            case domain = "Domain"
            case endpointDetails = "EndpointDetails"
            case endpointType = "EndpointType"
            case hostKey = "HostKey"
            case identityProviderDetails = "IdentityProviderDetails"
            case identityProviderType = "IdentityProviderType"
            case loggingRole = "LoggingRole"
            case protocols = "Protocols"
            case securityPolicyName = "SecurityPolicyName"
            case tags = "Tags"
        }
    }

    public struct CreateServerResponse: AWSDecodableShape {
        /// The service-assigned ID of the server that is created.
        public let serverId: String

        public init(serverId: String) {
            self.serverId = serverId
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
        }
    }

    public struct CreateUserRequest: AWSEncodableShape {
        /// The landing directory (folder) for a user when they log in to the server using the client. An example is  your-Amazon-S3-bucket-name&gt;/home/username .
        public let homeDirectory: String?
        /// Logical directory mappings that specify what Amazon S3 paths and keys should be visible to your user and how you want to make them visible. You will need to specify the "Entry" and "Target" pair, where Entry shows how the path is made visible and Target is the actual Amazon S3 path. If you only specify a target, it will be displayed as is. You will need to also make sure that your IAM role provides access to paths in Target. The following is an example.  '[ "/bucket2/documentation", { "Entry": "your-personal-report.pdf", "Target": "/bucket3/customized-reports/${transfer:UserName}.pdf" } ]'  In most cases, you can use this value instead of the scope-down policy to lock your user down to the designated home directory ("chroot"). To do this, you can set Entry to '/' and set Target to the HomeDirectory parameter value.  If the target of a logical directory entry does not exist in Amazon S3, the entry will be ignored. As a workaround, you can use the Amazon S3 API to create 0 byte objects as place holders for your directory. If using the CLI, use the s3api call instead of s3 so you can use the put-object operation. For example, you use the following: aws s3api put-object --bucket bucketname --key path/to/folder/. Make sure that the end of the key name ends in a '/' for it to be considered a folder.
        public let homeDirectoryMappings: [HomeDirectoryMapEntry]?
        /// The type of landing directory (folder) you want your users' home directory to be when they log into the server. If you set it to PATH, the user will see the absolute Amazon S3 bucket paths as is in their file transfer protocol clients. If you set it LOGICAL, you will need to provide mappings in the HomeDirectoryMappings for how you want to make Amazon S3 paths visible to your users.
        public let homeDirectoryType: HomeDirectoryType?
        /// A scope-down policy for your user so you can use the same IAM role across multiple users. This policy scopes down user access to portions of their Amazon S3 bucket. Variables that you can use inside this policy include ${Transfer:UserName}, ${Transfer:HomeDirectory}, and ${Transfer:HomeBucket}.  For scope-down policies, AWS Transfer Family stores the policy as a JSON blob, instead of the Amazon Resource Name (ARN) of the policy. You save the policy as a JSON blob and pass it in the Policy argument. For an example of a scope-down policy, see Creating a scope-down policy. For more information, see AssumeRole in the AWS Security Token Service API Reference.
        public let policy: String?
        public let posixProfile: PosixProfile?
        /// The IAM role that controls your users' access to your Amazon S3 bucket. The policies attached to this role will determine the level of access you want to provide your users when transferring files into and out of your Amazon S3 bucket or buckets. The IAM role should also contain a trust relationship that allows the server to access your resources when servicing your users' transfer requests.
        public let role: String
        /// A system-assigned unique identifier for a server instance. This is the specific server that you added your user to.
        public let serverId: String
        /// The public portion of the Secure Shell (SSH) key used to authenticate the user to the server.
        public let sshPublicKeyBody: String?
        /// Key-value pairs that can be used to group and search for users. Tags are metadata attached to users for any purpose.
        public let tags: [Tag]?
        /// A unique string that identifies a user and is associated with a as specified by the ServerId. This user name must be a minimum of 3 and a maximum of 100 characters long. The following are valid characters: a-z, A-Z, 0-9, underscore '_', hyphen '-', period '.', and at sign '@'. The user name can't start with a hyphen, period, or at sign.
        public let userName: String

        public init(homeDirectory: String? = nil, homeDirectoryMappings: [HomeDirectoryMapEntry]? = nil, homeDirectoryType: HomeDirectoryType? = nil, policy: String? = nil, posixProfile: PosixProfile? = nil, role: String, serverId: String, sshPublicKeyBody: String? = nil, tags: [Tag]? = nil, userName: String) {
            self.homeDirectory = homeDirectory
            self.homeDirectoryMappings = homeDirectoryMappings
            self.homeDirectoryType = homeDirectoryType
            self.policy = policy
            self.posixProfile = posixProfile
            self.role = role
            self.serverId = serverId
            self.sshPublicKeyBody = sshPublicKeyBody
            self.tags = tags
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.homeDirectory, name: "homeDirectory", parent: name, max: 1024)
            try self.validate(self.homeDirectory, name: "homeDirectory", parent: name, pattern: "^$|/.*")
            try self.homeDirectoryMappings?.forEach {
                try $0.validate(name: "\(name).homeDirectoryMappings[]")
            }
            try self.validate(self.homeDirectoryMappings, name: "homeDirectoryMappings", parent: name, max: 50)
            try self.validate(self.homeDirectoryMappings, name: "homeDirectoryMappings", parent: name, min: 1)
            try self.validate(self.policy, name: "policy", parent: name, max: 2048)
            try self.posixProfile?.validate(name: "\(name).posixProfile")
            try self.validate(self.role, name: "role", parent: name, max: 2048)
            try self.validate(self.role, name: "role", parent: name, min: 20)
            try self.validate(self.role, name: "role", parent: name, pattern: "arn:.*role/.*")
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.sshPublicKeyBody, name: "sshPublicKeyBody", parent: name, max: 2048)
            try self.validate(self.sshPublicKeyBody, name: "sshPublicKeyBody", parent: name, pattern: "^ssh-rsa\\s+[A-Za-z0-9+/]+[=]{0,3}(\\s+.+)?\\s*$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
        }

        private enum CodingKeys: String, CodingKey {
            case homeDirectory = "HomeDirectory"
            case homeDirectoryMappings = "HomeDirectoryMappings"
            case homeDirectoryType = "HomeDirectoryType"
            case policy = "Policy"
            case posixProfile = "PosixProfile"
            case role = "Role"
            case serverId = "ServerId"
            case sshPublicKeyBody = "SshPublicKeyBody"
            case tags = "Tags"
            case userName = "UserName"
        }
    }

    public struct CreateUserResponse: AWSDecodableShape {
        /// The ID of the server that the user is attached to.
        public let serverId: String
        /// A unique string that identifies a user account associated with a server.
        public let userName: String

        public init(serverId: String, userName: String) {
            self.serverId = serverId
            self.userName = userName
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case userName = "UserName"
        }
    }

    public struct DeleteServerRequest: AWSEncodableShape {
        /// A unique system-assigned identifier for a server instance.
        public let serverId: String

        public init(serverId: String) {
            self.serverId = serverId
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
        }
    }

    public struct DeleteSshPublicKeyRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a file transfer protocol-enabled server instance that has the user assigned to it.
        public let serverId: String
        /// A unique identifier used to reference your user's specific SSH key.
        public let sshPublicKeyId: String
        /// A unique string that identifies a user whose public key is being deleted.
        public let userName: String

        public init(serverId: String, sshPublicKeyId: String, userName: String) {
            self.serverId = serverId
            self.sshPublicKeyId = sshPublicKeyId
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.sshPublicKeyId, name: "sshPublicKeyId", parent: name, max: 21)
            try self.validate(self.sshPublicKeyId, name: "sshPublicKeyId", parent: name, min: 21)
            try self.validate(self.sshPublicKeyId, name: "sshPublicKeyId", parent: name, pattern: "^key-[0-9a-f]{17}$")
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case sshPublicKeyId = "SshPublicKeyId"
            case userName = "UserName"
        }
    }

    public struct DeleteUserRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a server instance that has the user assigned to it.
        public let serverId: String
        /// A unique string that identifies a user that is being deleted from a server.
        public let userName: String

        public init(serverId: String, userName: String) {
            self.serverId = serverId
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case userName = "UserName"
        }
    }

    public struct DescribeSecurityPolicyRequest: AWSEncodableShape {
        /// Specifies the name of the security policy that is attached to the server.
        public let securityPolicyName: String

        public init(securityPolicyName: String) {
            self.securityPolicyName = securityPolicyName
        }

        public func validate(name: String) throws {
            try self.validate(self.securityPolicyName, name: "securityPolicyName", parent: name, max: 100)
            try self.validate(self.securityPolicyName, name: "securityPolicyName", parent: name, pattern: "TransferSecurityPolicy-.+")
        }

        private enum CodingKeys: String, CodingKey {
            case securityPolicyName = "SecurityPolicyName"
        }
    }

    public struct DescribeSecurityPolicyResponse: AWSDecodableShape {
        /// An array containing the properties of the security policy.
        public let securityPolicy: DescribedSecurityPolicy

        public init(securityPolicy: DescribedSecurityPolicy) {
            self.securityPolicy = securityPolicy
        }

        private enum CodingKeys: String, CodingKey {
            case securityPolicy = "SecurityPolicy"
        }
    }

    public struct DescribeServerRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a server.
        public let serverId: String

        public init(serverId: String) {
            self.serverId = serverId
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
        }
    }

    public struct DescribeServerResponse: AWSDecodableShape {
        /// An array containing the properties of a server with the ServerID you specified.
        public let server: DescribedServer

        public init(server: DescribedServer) {
            self.server = server
        }

        private enum CodingKeys: String, CodingKey {
            case server = "Server"
        }
    }

    public struct DescribeUserRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a server that has this user assigned.
        public let serverId: String
        /// The name of the user assigned to one or more servers. User names are part of the sign-in credentials to use the AWS Transfer Family service and perform file transfer tasks.
        public let userName: String

        public init(serverId: String, userName: String) {
            self.serverId = serverId
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case userName = "UserName"
        }
    }

    public struct DescribeUserResponse: AWSDecodableShape {
        /// A system-assigned unique identifier for a server that has this user assigned.
        public let serverId: String
        /// An array containing the properties of the user account for the ServerID value that you specified.
        public let user: DescribedUser

        public init(serverId: String, user: DescribedUser) {
            self.serverId = serverId
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case user = "User"
        }
    }

    public struct DescribedSecurityPolicy: AWSDecodableShape {
        /// Specifies whether this policy enables Federal Information Processing Standards (FIPS).
        public let fips: Bool?
        /// Specifies the name of the security policy that is attached to the server.
        public let securityPolicyName: String
        /// Specifies the enabled Secure Shell (SSH) cipher encryption algorithms in the security policy that is attached to the server.
        public let sshCiphers: [String]?
        /// Specifies the enabled SSH key exchange (KEX) encryption algorithms in the security policy that is attached to the server.
        public let sshKexs: [String]?
        /// Specifies the enabled SSH message authentication code (MAC) encryption algorithms in the security policy that is attached to the server.
        public let sshMacs: [String]?
        /// Specifies the enabled Transport Layer Security (TLS) cipher encryption algorithms in the security policy that is attached to the server.
        public let tlsCiphers: [String]?

        public init(fips: Bool? = nil, securityPolicyName: String, sshCiphers: [String]? = nil, sshKexs: [String]? = nil, sshMacs: [String]? = nil, tlsCiphers: [String]? = nil) {
            self.fips = fips
            self.securityPolicyName = securityPolicyName
            self.sshCiphers = sshCiphers
            self.sshKexs = sshKexs
            self.sshMacs = sshMacs
            self.tlsCiphers = tlsCiphers
        }

        private enum CodingKeys: String, CodingKey {
            case fips = "Fips"
            case securityPolicyName = "SecurityPolicyName"
            case sshCiphers = "SshCiphers"
            case sshKexs = "SshKexs"
            case sshMacs = "SshMacs"
            case tlsCiphers = "TlsCiphers"
        }
    }

    public struct DescribedServer: AWSDecodableShape {
        /// Specifies the unique Amazon Resource Name (ARN) of the server.
        public let arn: String
        /// Specifies the ARN of the AWS Certificate Manager (ACM) certificate. Required when Protocols is set to FTPS.
        public let certificate: String?
        public let domain: Domain?
        /// Specifies the virtual private cloud (VPC) endpoint settings that you configured for your server.
        public let endpointDetails: EndpointDetails?
        /// Defines the type of endpoint that your server is connected to. If your server is connected to a VPC endpoint, your server isn't accessible over the public internet.
        public let endpointType: EndpointType?
        /// Specifies the Base64-encoded SHA256 fingerprint of the server's host key. This value is equivalent to the output of the ssh-keygen -l -f my-new-server-key command.
        public let hostKeyFingerprint: String?
        /// Specifies information to call a customer-supplied authentication API. This field is not populated when the IdentityProviderType of a server is SERVICE_MANAGED.
        public let identityProviderDetails: IdentityProviderDetails?
        /// Specifies the mode of authentication method enabled for this service. A value of SERVICE_MANAGED means that you are using this server to store and access user credentials within the service. A value of API_GATEWAY indicates that you have integrated an API Gateway endpoint that will be invoked for authenticating your user into the service.
        public let identityProviderType: IdentityProviderType?
        /// Specifies the AWS Identity and Access Management (IAM) role that allows a server to turn on Amazon CloudWatch logging for Amazon S3 events. When set, user activity can be viewed in your CloudWatch logs.
        public let loggingRole: String?
        /// Specifies the file transfer protocol or protocols over which your file transfer protocol client can connect to your server's endpoint. The available protocols are:    SFTP (Secure Shell (SSH) File Transfer Protocol): File transfer over SSH    FTPS (File Transfer Protocol Secure): File transfer with TLS encryption    FTP (File Transfer Protocol): Unencrypted file transfer
        public let protocols: [Protocol]?
        /// Specifies the name of the security policy that is attached to the server.
        public let securityPolicyName: String?
        /// Specifies the unique system-assigned identifier for a server that you instantiate.
        public let serverId: String?
        /// Specifies the condition of a server for the server that was described. A value of ONLINE indicates that the server can accept jobs and transfer files. A State value of OFFLINE means that the server cannot perform file transfer operations. The states of STARTING and STOPPING indicate that the server is in an intermediate state, either not fully able to respond, or not fully offline. The values of START_FAILED or STOP_FAILED can indicate an error condition.
        public let state: State?
        /// Specifies the key-value pairs that you can use to search for and group servers that were assigned to the server that was described.
        public let tags: [Tag]?
        /// Specifies the number of users that are assigned to a server you specified with the ServerId.
        public let userCount: Int?

        public init(arn: String, certificate: String? = nil, domain: Domain? = nil, endpointDetails: EndpointDetails? = nil, endpointType: EndpointType? = nil, hostKeyFingerprint: String? = nil, identityProviderDetails: IdentityProviderDetails? = nil, identityProviderType: IdentityProviderType? = nil, loggingRole: String? = nil, protocols: [Protocol]? = nil, securityPolicyName: String? = nil, serverId: String? = nil, state: State? = nil, tags: [Tag]? = nil, userCount: Int? = nil) {
            self.arn = arn
            self.certificate = certificate
            self.domain = domain
            self.endpointDetails = endpointDetails
            self.endpointType = endpointType
            self.hostKeyFingerprint = hostKeyFingerprint
            self.identityProviderDetails = identityProviderDetails
            self.identityProviderType = identityProviderType
            self.loggingRole = loggingRole
            self.protocols = protocols
            self.securityPolicyName = securityPolicyName
            self.serverId = serverId
            self.state = state
            self.tags = tags
            self.userCount = userCount
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case certificate = "Certificate"
            case domain = "Domain"
            case endpointDetails = "EndpointDetails"
            case endpointType = "EndpointType"
            case hostKeyFingerprint = "HostKeyFingerprint"
            case identityProviderDetails = "IdentityProviderDetails"
            case identityProviderType = "IdentityProviderType"
            case loggingRole = "LoggingRole"
            case protocols = "Protocols"
            case securityPolicyName = "SecurityPolicyName"
            case serverId = "ServerId"
            case state = "State"
            case tags = "Tags"
            case userCount = "UserCount"
        }
    }

    public struct DescribedUser: AWSDecodableShape {
        /// Specifies the unique Amazon Resource Name (ARN) for the user that was requested to be described.
        public let arn: String
        /// Specifies the landing directory (or folder), which is the location that files are written to or read from in an Amazon S3 bucket, for the described user. An example is  your-Amazon-S3-bucket-name&gt;/home/username .
        public let homeDirectory: String?
        /// Specifies the logical directory mappings that specify what Amazon S3 paths and keys should be visible to your user and how you want to make them visible. You will need to specify the "Entry" and "Target" pair, where Entry shows how the path is made visible and Target is the actual Amazon S3 path. If you only specify a target, it will be displayed as is. You will need to also make sure that your AWS Identity and Access Management (IAM) role provides access to paths in Target. In most cases, you can use this value instead of the scope-down policy to lock your user down to the designated home directory ("chroot"). To do this, you can set Entry to '/' and set Target to the HomeDirectory parameter value.
        public let homeDirectoryMappings: [HomeDirectoryMapEntry]?
        /// Specifies the type of landing directory (folder) you mapped for your users to see when they log into the file transfer protocol-enabled server. If you set it to PATH, the user will see the absolute Amazon S3 bucket paths as is in their file transfer protocol clients. If you set it LOGICAL, you will need to provide mappings in the HomeDirectoryMappings for how you want to make Amazon S3 paths visible to your users.
        public let homeDirectoryType: HomeDirectoryType?
        /// Specifies the name of the policy in use for the described user.
        public let policy: String?
        public let posixProfile: PosixProfile?
        /// Specifies the IAM role that controls your users' access to your Amazon S3 bucket. The policies attached to this role will determine the level of access you want to provide your users when transferring files into and out of your Amazon S3 bucket or buckets. The IAM role should also contain a trust relationship that allows a server to access your resources when servicing your users' transfer requests.
        public let role: String?
        /// Specifies the public key portion of the Secure Shell (SSH) keys stored for the described user.
        public let sshPublicKeys: [SshPublicKey]?
        /// Specifies the key-value pairs for the user requested. Tag can be used to search for and group users for a variety of purposes.
        public let tags: [Tag]?
        /// Specifies the name of the user that was requested to be described. User names are used for authentication purposes. This is the string that will be used by your user when they log in to your server.
        public let userName: String?

        public init(arn: String, homeDirectory: String? = nil, homeDirectoryMappings: [HomeDirectoryMapEntry]? = nil, homeDirectoryType: HomeDirectoryType? = nil, policy: String? = nil, posixProfile: PosixProfile? = nil, role: String? = nil, sshPublicKeys: [SshPublicKey]? = nil, tags: [Tag]? = nil, userName: String? = nil) {
            self.arn = arn
            self.homeDirectory = homeDirectory
            self.homeDirectoryMappings = homeDirectoryMappings
            self.homeDirectoryType = homeDirectoryType
            self.policy = policy
            self.posixProfile = posixProfile
            self.role = role
            self.sshPublicKeys = sshPublicKeys
            self.tags = tags
            self.userName = userName
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case homeDirectory = "HomeDirectory"
            case homeDirectoryMappings = "HomeDirectoryMappings"
            case homeDirectoryType = "HomeDirectoryType"
            case policy = "Policy"
            case posixProfile = "PosixProfile"
            case role = "Role"
            case sshPublicKeys = "SshPublicKeys"
            case tags = "Tags"
            case userName = "UserName"
        }
    }

    public struct EndpointDetails: AWSEncodableShape & AWSDecodableShape {
        /// A list of address allocation IDs that are required to attach an Elastic IP address to your server's endpoint.  This property can only be set when EndpointType is set to VPC and it is only valid in the UpdateServer API.
        public let addressAllocationIds: [String]?
        /// A list of security groups IDs that are available to attach to your server's endpoint.  This property can only be set when EndpointType is set to VPC. You can only edit the SecurityGroupIds property in the UpdateServer API and only if you are changing the EndpointType from PUBLIC or VPC_ENDPOINT to VPC.
        public let securityGroupIds: [String]?
        /// A list of subnet IDs that are required to host your server endpoint in your VPC.  This property can only be set when EndpointType is set to VPC.
        public let subnetIds: [String]?
        /// The ID of the VPC endpoint.  This property can only be set when EndpointType is set to VPC_ENDPOINT.
        public let vpcEndpointId: String?
        /// The VPC ID of the VPC in which a server's endpoint will be hosted.  This property can only be set when EndpointType is set to VPC.
        public let vpcId: String?

        public init(addressAllocationIds: [String]? = nil, securityGroupIds: [String]? = nil, subnetIds: [String]? = nil, vpcEndpointId: String? = nil, vpcId: String? = nil) {
            self.addressAllocationIds = addressAllocationIds
            self.securityGroupIds = securityGroupIds
            self.subnetIds = subnetIds
            self.vpcEndpointId = vpcEndpointId
            self.vpcId = vpcId
        }

        public func validate(name: String) throws {
            try self.securityGroupIds?.forEach {
                try validate($0, name: "securityGroupIds[]", parent: name, max: 20)
                try validate($0, name: "securityGroupIds[]", parent: name, min: 11)
                try validate($0, name: "securityGroupIds[]", parent: name, pattern: "^sg-[0-9a-f]{8,17}$")
            }
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, max: 22)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, min: 22)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, pattern: "^vpce-[0-9a-f]{17}$")
        }

        private enum CodingKeys: String, CodingKey {
            case addressAllocationIds = "AddressAllocationIds"
            case securityGroupIds = "SecurityGroupIds"
            case subnetIds = "SubnetIds"
            case vpcEndpointId = "VpcEndpointId"
            case vpcId = "VpcId"
        }
    }

    public struct HomeDirectoryMapEntry: AWSEncodableShape & AWSDecodableShape {
        /// Represents an entry and a target for HomeDirectoryMappings.
        public let entry: String
        /// Represents the map target that is used in a HomeDirectorymapEntry.
        public let target: String

        public init(entry: String, target: String) {
            self.entry = entry
            self.target = target
        }

        public func validate(name: String) throws {
            try self.validate(self.entry, name: "entry", parent: name, max: 1024)
            try self.validate(self.entry, name: "entry", parent: name, pattern: "^/.*")
            try self.validate(self.target, name: "target", parent: name, max: 1024)
            try self.validate(self.target, name: "target", parent: name, pattern: "^/.*")
        }

        private enum CodingKeys: String, CodingKey {
            case entry = "Entry"
            case target = "Target"
        }
    }

    public struct IdentityProviderDetails: AWSEncodableShape & AWSDecodableShape {
        /// Provides the type of InvocationRole used to authenticate the user account.
        public let invocationRole: String?
        /// Provides the location of the service endpoint used to authenticate users.
        public let url: String?

        public init(invocationRole: String? = nil, url: String? = nil) {
            self.invocationRole = invocationRole
            self.url = url
        }

        public func validate(name: String) throws {
            try self.validate(self.invocationRole, name: "invocationRole", parent: name, max: 2048)
            try self.validate(self.invocationRole, name: "invocationRole", parent: name, min: 20)
            try self.validate(self.invocationRole, name: "invocationRole", parent: name, pattern: "arn:.*role/.*")
            try self.validate(self.url, name: "url", parent: name, max: 255)
        }

        private enum CodingKeys: String, CodingKey {
            case invocationRole = "InvocationRole"
            case url = "Url"
        }
    }

    public struct ImportSshPublicKeyRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a server.
        public let serverId: String
        /// The public key portion of an SSH key pair.
        public let sshPublicKeyBody: String
        /// The name of the user account that is assigned to one or more servers.
        public let userName: String

        public init(serverId: String, sshPublicKeyBody: String, userName: String) {
            self.serverId = serverId
            self.sshPublicKeyBody = sshPublicKeyBody
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.sshPublicKeyBody, name: "sshPublicKeyBody", parent: name, max: 2048)
            try self.validate(self.sshPublicKeyBody, name: "sshPublicKeyBody", parent: name, pattern: "^ssh-rsa\\s+[A-Za-z0-9+/]+[=]{0,3}(\\s+.+)?\\s*$")
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case sshPublicKeyBody = "SshPublicKeyBody"
            case userName = "UserName"
        }
    }

    public struct ImportSshPublicKeyResponse: AWSDecodableShape {
        /// A system-assigned unique identifier for a server.
        public let serverId: String
        /// The name given to a public key by the system that was imported.
        public let sshPublicKeyId: String
        /// A user name assigned to the ServerID value that you specified.
        public let userName: String

        public init(serverId: String, sshPublicKeyId: String, userName: String) {
            self.serverId = serverId
            self.sshPublicKeyId = sshPublicKeyId
            self.userName = userName
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case sshPublicKeyId = "SshPublicKeyId"
            case userName = "UserName"
        }
    }

    public struct ListSecurityPoliciesRequest: AWSEncodableShape {
        /// Specifies the number of security policies to return as a response to the ListSecurityPolicies query.
        public let maxResults: Int?
        /// When additional results are obtained from the ListSecurityPolicies command, a NextToken parameter is returned in the output. You can then pass the NextToken parameter in a subsequent command to continue listing additional security policies.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListSecurityPoliciesResponse: AWSDecodableShape {
        /// When you can get additional results from the ListSecurityPolicies operation, a NextToken parameter is returned in the output. In a following command, you can pass in the NextToken parameter to continue listing security policies.
        public let nextToken: String?
        /// An array of security policies that were listed.
        public let securityPolicyNames: [String]

        public init(nextToken: String? = nil, securityPolicyNames: [String]) {
            self.nextToken = nextToken
            self.securityPolicyNames = securityPolicyNames
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case securityPolicyNames = "SecurityPolicyNames"
        }
    }

    public struct ListServersRequest: AWSEncodableShape {
        /// Specifies the number of servers to return as a response to the ListServers query.
        public let maxResults: Int?
        /// When additional results are obtained from the ListServers command, a NextToken parameter is returned in the output. You can then pass the NextToken parameter in a subsequent command to continue listing additional servers.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListServersResponse: AWSDecodableShape {
        /// When you can get additional results from the ListServers operation, a NextToken parameter is returned in the output. In a following command, you can pass in the NextToken parameter to continue listing additional servers.
        public let nextToken: String?
        /// An array of servers that were listed.
        public let servers: [ListedServer]

        public init(nextToken: String? = nil, servers: [ListedServer]) {
            self.nextToken = nextToken
            self.servers = servers
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case servers = "Servers"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// Requests the tags associated with a particular Amazon Resource Name (ARN). An ARN is an identifier for a specific AWS resource, such as a server, user, or role.
        public let arn: String
        /// Specifies the number of tags to return as a response to the ListTagsForResource request.
        public let maxResults: Int?
        /// When you request additional results from the ListTagsForResource operation, a NextToken parameter is returned in the input. You can then pass in a subsequent command to the NextToken parameter to continue listing additional tags.
        public let nextToken: String?

        public init(arn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.arn = arn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 1600)
            try self.validate(self.arn, name: "arn", parent: name, min: 20)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "arn:.*")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The ARN you specified to list the tags of.
        public let arn: String?
        /// When you can get additional results from the ListTagsForResource call, a NextToken parameter is returned in the output. You can then pass in a subsequent command to the NextToken parameter to continue listing additional tags.
        public let nextToken: String?
        /// Key-value pairs that are assigned to a resource, usually for the purpose of grouping and searching for items. Tags are metadata that you define.
        public let tags: [Tag]?

        public init(arn: String? = nil, nextToken: String? = nil, tags: [Tag]? = nil) {
            self.arn = arn
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct ListUsersRequest: AWSEncodableShape {
        /// Specifies the number of users to return as a response to the ListUsers request.
        public let maxResults: Int?
        /// When you can get additional results from the ListUsers call, a NextToken parameter is returned in the output. You can then pass in a subsequent command to the NextToken parameter to continue listing additional users.
        public let nextToken: String?
        /// A system-assigned unique identifier for a server that has users assigned to it.
        public let serverId: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, serverId: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serverId = serverId
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case serverId = "ServerId"
        }
    }

    public struct ListUsersResponse: AWSDecodableShape {
        /// When you can get additional results from the ListUsers call, a NextToken parameter is returned in the output. You can then pass in a subsequent command to the NextToken parameter to continue listing additional users.
        public let nextToken: String?
        /// A system-assigned unique identifier for a server that the users are assigned to.
        public let serverId: String
        /// Returns the user accounts and their properties for the ServerId value that you specify.
        public let users: [ListedUser]

        public init(nextToken: String? = nil, serverId: String, users: [ListedUser]) {
            self.nextToken = nextToken
            self.serverId = serverId
            self.users = users
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case serverId = "ServerId"
            case users = "Users"
        }
    }

    public struct ListedServer: AWSDecodableShape {
        /// Specifies the unique Amazon Resource Name (ARN) for a server to be listed.
        public let arn: String
        public let domain: Domain?
        /// Specifies the type of VPC endpoint that your server is connected to. If your server is connected to a VPC endpoint, your server isn't accessible over the public internet.
        public let endpointType: EndpointType?
        /// Specifies the authentication method used to validate a user for a server that was specified. This can include Secure Shell (SSH), user name and password combinations, or your own custom authentication method. Valid values include SERVICE_MANAGED or API_GATEWAY.
        public let identityProviderType: IdentityProviderType?
        /// Specifies the AWS Identity and Access Management (IAM) role that allows a server to turn on Amazon CloudWatch logging.
        public let loggingRole: String?
        /// Specifies the unique system assigned identifier for the servers that were listed.
        public let serverId: String?
        /// Specifies the condition of a server for the server that was described. A value of ONLINE indicates that the server can accept jobs and transfer files. A State value of OFFLINE means that the server cannot perform file transfer operations. The states of STARTING and STOPPING indicate that the server is in an intermediate state, either not fully able to respond, or not fully offline. The values of START_FAILED or STOP_FAILED can indicate an error condition.
        public let state: State?
        /// Specifies the number of users that are assigned to a server you specified with the ServerId.
        public let userCount: Int?

        public init(arn: String, domain: Domain? = nil, endpointType: EndpointType? = nil, identityProviderType: IdentityProviderType? = nil, loggingRole: String? = nil, serverId: String? = nil, state: State? = nil, userCount: Int? = nil) {
            self.arn = arn
            self.domain = domain
            self.endpointType = endpointType
            self.identityProviderType = identityProviderType
            self.loggingRole = loggingRole
            self.serverId = serverId
            self.state = state
            self.userCount = userCount
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case domain = "Domain"
            case endpointType = "EndpointType"
            case identityProviderType = "IdentityProviderType"
            case loggingRole = "LoggingRole"
            case serverId = "ServerId"
            case state = "State"
            case userCount = "UserCount"
        }
    }

    public struct ListedUser: AWSDecodableShape {
        /// Provides the unique Amazon Resource Name (ARN) for the user that you want to learn about.
        public let arn: String
        /// Specifies the location that files are written to or read from an Amazon S3 bucket for the user you specify by their ARN.
        public let homeDirectory: String?
        /// Specifies the type of landing directory (folder) you mapped for your users' home directory. If you set it to PATH, the user will see the absolute Amazon S3 bucket paths as is in their file transfer protocol clients. If you set it LOGICAL, you will need to provide mappings in the HomeDirectoryMappings for how you want to make Amazon S3 paths visible to your users.
        public let homeDirectoryType: HomeDirectoryType?
        /// Specifies the role that is in use by this user. A role is an AWS Identity and Access Management (IAM) entity that, in this case, allows a file transfer protocol-enabled server to act on a user's behalf. It allows the server to inherit the trust relationship that enables that user to perform file operations to their Amazon S3 bucket.
        public let role: String?
        /// Specifies the number of SSH public keys stored for the user you specified.
        public let sshPublicKeyCount: Int?
        /// Specifies the name of the user whose ARN was specified. User names are used for authentication purposes.
        public let userName: String?

        public init(arn: String, homeDirectory: String? = nil, homeDirectoryType: HomeDirectoryType? = nil, role: String? = nil, sshPublicKeyCount: Int? = nil, userName: String? = nil) {
            self.arn = arn
            self.homeDirectory = homeDirectory
            self.homeDirectoryType = homeDirectoryType
            self.role = role
            self.sshPublicKeyCount = sshPublicKeyCount
            self.userName = userName
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case homeDirectory = "HomeDirectory"
            case homeDirectoryType = "HomeDirectoryType"
            case role = "Role"
            case sshPublicKeyCount = "SshPublicKeyCount"
            case userName = "UserName"
        }
    }

    public struct PosixProfile: AWSEncodableShape & AWSDecodableShape {
        public let gid: Int64
        public let secondaryGids: [Int64]?
        public let uid: Int64

        public init(gid: Int64, secondaryGids: [Int64]? = nil, uid: Int64) {
            self.gid = gid
            self.secondaryGids = secondaryGids
            self.uid = uid
        }

        public func validate(name: String) throws {
            try self.validate(self.gid, name: "gid", parent: name, max: 4_294_967_295)
            try self.validate(self.gid, name: "gid", parent: name, min: 0)
            try self.secondaryGids?.forEach {
                try validate($0, name: "secondaryGids[]", parent: name, max: 4_294_967_295)
                try validate($0, name: "secondaryGids[]", parent: name, min: 0)
            }
            try self.validate(self.secondaryGids, name: "secondaryGids", parent: name, max: 16)
            try self.validate(self.secondaryGids, name: "secondaryGids", parent: name, min: 0)
            try self.validate(self.uid, name: "uid", parent: name, max: 4_294_967_295)
            try self.validate(self.uid, name: "uid", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case gid = "Gid"
            case secondaryGids = "SecondaryGids"
            case uid = "Uid"
        }
    }

    public struct SshPublicKey: AWSDecodableShape {
        /// Specifies the date that the public key was added to the user account.
        public let dateImported: Date
        /// Specifies the content of the SSH public key as specified by the PublicKeyId.
        public let sshPublicKeyBody: String
        /// Specifies the SshPublicKeyId parameter contains the identifier of the public key.
        public let sshPublicKeyId: String

        public init(dateImported: Date, sshPublicKeyBody: String, sshPublicKeyId: String) {
            self.dateImported = dateImported
            self.sshPublicKeyBody = sshPublicKeyBody
            self.sshPublicKeyId = sshPublicKeyId
        }

        private enum CodingKeys: String, CodingKey {
            case dateImported = "DateImported"
            case sshPublicKeyBody = "SshPublicKeyBody"
            case sshPublicKeyId = "SshPublicKeyId"
        }
    }

    public struct StartServerRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a server that you start.
        public let serverId: String

        public init(serverId: String) {
            self.serverId = serverId
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
        }
    }

    public struct StopServerRequest: AWSEncodableShape {
        /// A system-assigned unique identifier for a server that you stopped.
        public let serverId: String

        public init(serverId: String) {
            self.serverId = serverId
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The name assigned to the tag that you create.
        public let key: String
        /// Contains one or more values that you assigned to the key name you create.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.value, name: "value", parent: name, max: 256)
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// An Amazon Resource Name (ARN) for a specific AWS resource, such as a server, user, or role.
        public let arn: String
        /// Key-value pairs assigned to ARNs that you can use to group and search for resources by type. You can attach this metadata to user accounts for any purpose.
        public let tags: [Tag]

        public init(arn: String, tags: [Tag]) {
            self.arn = arn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 1600)
            try self.validate(self.arn, name: "arn", parent: name, min: 20)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "arn:.*")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case tags = "Tags"
        }
    }

    public struct TestIdentityProviderRequest: AWSEncodableShape {
        /// A system-assigned identifier for a specific server. That server's user authentication method is tested with a user name and password.
        public let serverId: String
        /// The type of file transfer protocol to be tested. The available protocols are:   Secure Shell (SSH) File Transfer Protocol (SFTP)   File Transfer Protocol Secure (FTPS)   File Transfer Protocol (FTP)
        public let serverProtocol: Protocol?
        /// The source IP address of the user account to be tested.
        public let sourceIp: String?
        /// The name of the user account to be tested.
        public let userName: String
        /// The password of the user account to be tested.
        public let userPassword: String?

        public init(serverId: String, serverProtocol: Protocol? = nil, sourceIp: String? = nil, userName: String, userPassword: String? = nil) {
            self.serverId = serverId
            self.serverProtocol = serverProtocol
            self.sourceIp = sourceIp
            self.userName = userName
            self.userPassword = userPassword
        }

        public func validate(name: String) throws {
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.sourceIp, name: "sourceIp", parent: name, max: 32)
            try self.validate(self.sourceIp, name: "sourceIp", parent: name, pattern: "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$")
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
            try self.validate(self.userPassword, name: "userPassword", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case serverProtocol = "ServerProtocol"
            case sourceIp = "SourceIp"
            case userName = "UserName"
            case userPassword = "UserPassword"
        }
    }

    public struct TestIdentityProviderResponse: AWSDecodableShape {
        /// A message that indicates whether the test was successful or not.
        public let message: String?
        /// The response that is returned from your API Gateway.
        public let response: String?
        /// The HTTP status code that is the response from your API Gateway.
        public let statusCode: Int
        /// The endpoint of the service used to authenticate a user.
        public let url: String

        public init(message: String? = nil, response: String? = nil, statusCode: Int, url: String) {
            self.message = message
            self.response = response
            self.statusCode = statusCode
            self.url = url
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case response = "Response"
            case statusCode = "StatusCode"
            case url = "Url"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The value of the resource that will have the tag removed. An Amazon Resource Name (ARN) is an identifier for a specific AWS resource, such as a server, user, or role.
        public let arn: String
        /// TagKeys are key-value pairs assigned to ARNs that can be used to group and search for resources by type. This metadata can be attached to resources for any purpose.
        public let tagKeys: [String]

        public init(arn: String, tagKeys: [String]) {
            self.arn = arn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 1600)
            try self.validate(self.arn, name: "arn", parent: name, min: 20)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "arn:.*")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UpdateServerRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the AWS Certificate Manager (ACM) certificate. Required when Protocols is set to FTPS. To request a new public certificate, see Request a public certificate in the  AWS Certificate Manager User Guide. To import an existing certificate into ACM, see Importing certificates into ACM in the  AWS Certificate Manager User Guide. To request a private certificate to use FTPS through private IP addresses, see Request a private certificate in the  AWS Certificate Manager User Guide. Certificates with the following cryptographic algorithms and key sizes are supported:   2048-bit RSA (RSA_2048)   4096-bit RSA (RSA_4096)   Elliptic Prime Curve 256 bit (EC_prime256v1)   Elliptic Prime Curve 384 bit (EC_secp384r1)   Elliptic Prime Curve 521 bit (EC_secp521r1)    The certificate must be a valid SSL/TLS X.509 version 3 certificate with FQDN or IP address specified and information about the issuer.
        public let certificate: String?
        /// The virtual private cloud (VPC) endpoint settings that are configured for your server. With a VPC endpoint, you can restrict access to your server to resources only within your VPC. To control incoming internet traffic, you will need to associate one or more Elastic IP addresses with your server's endpoint.
        public let endpointDetails: EndpointDetails?
        /// The type of endpoint that you want your server to connect to. You can choose to connect to the public internet or a VPC endpoint. With a VPC endpoint, you can restrict access to your server and resources only within your VPC.  It is recommended that you use VPC as the EndpointType. With this endpoint type, you have the option to directly associate up to three Elastic IPv4 addresses (BYO IP included) with your server's endpoint and use VPC security groups to restrict traffic by the client's public IP address. This is not possible with EndpointType set to VPC_ENDPOINT.
        public let endpointType: EndpointType?
        /// The RSA private key as generated by ssh-keygen -N "" -m PEM -f my-new-server-key.  If you aren't planning to migrate existing users from an existing server to a new server, don't update the host key. Accidentally changing a server's host key can be disruptive.  For more information, see Change the host key for your SFTP-enabled server in the AWS Transfer Family User Guide.
        public let hostKey: String?
        /// An array containing all of the information required to call a customer's authentication API method.
        public let identityProviderDetails: IdentityProviderDetails?
        /// Changes the AWS Identity and Access Management (IAM) role that allows Amazon S3 events to be logged in Amazon CloudWatch, turning logging on or off.
        public let loggingRole: String?
        /// Specifies the file transfer protocol or protocols over which your file transfer protocol client can connect to your server's endpoint. The available protocols are:   Secure Shell (SSH) File Transfer Protocol (SFTP): File transfer over SSH   File Transfer Protocol Secure (FTPS): File transfer with TLS encryption   File Transfer Protocol (FTP): Unencrypted file transfer    If you select FTPS, you must choose a certificate stored in AWS Certificate Manager (ACM) which will be used to identify your server when clients connect to it over FTPS. If Protocol includes either FTP or FTPS, then the EndpointType must be VPC and the IdentityProviderType must be API_GATEWAY. If Protocol includes FTP, then AddressAllocationIds cannot be associated. If Protocol is set only to SFTP, the EndpointType can be set to PUBLIC and the IdentityProviderType can be set to SERVICE_MANAGED.
        public let protocols: [Protocol]?
        /// Specifies the name of the security policy that is attached to the server.
        public let securityPolicyName: String?
        /// A system-assigned unique identifier for a server instance that the user account is assigned to.
        public let serverId: String

        public init(certificate: String? = nil, endpointDetails: EndpointDetails? = nil, endpointType: EndpointType? = nil, hostKey: String? = nil, identityProviderDetails: IdentityProviderDetails? = nil, loggingRole: String? = nil, protocols: [Protocol]? = nil, securityPolicyName: String? = nil, serverId: String) {
            self.certificate = certificate
            self.endpointDetails = endpointDetails
            self.endpointType = endpointType
            self.hostKey = hostKey
            self.identityProviderDetails = identityProviderDetails
            self.loggingRole = loggingRole
            self.protocols = protocols
            self.securityPolicyName = securityPolicyName
            self.serverId = serverId
        }

        public func validate(name: String) throws {
            try self.validate(self.certificate, name: "certificate", parent: name, max: 1600)
            try self.endpointDetails?.validate(name: "\(name).endpointDetails")
            try self.validate(self.hostKey, name: "hostKey", parent: name, max: 4096)
            try self.identityProviderDetails?.validate(name: "\(name).identityProviderDetails")
            try self.validate(self.loggingRole, name: "loggingRole", parent: name, max: 2048)
            try self.validate(self.loggingRole, name: "loggingRole", parent: name, pattern: "^$|arn:.*role/.*")
            try self.validate(self.protocols, name: "protocols", parent: name, max: 3)
            try self.validate(self.protocols, name: "protocols", parent: name, min: 1)
            try self.validate(self.securityPolicyName, name: "securityPolicyName", parent: name, max: 100)
            try self.validate(self.securityPolicyName, name: "securityPolicyName", parent: name, pattern: "TransferSecurityPolicy-.+")
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
        }

        private enum CodingKeys: String, CodingKey {
            case certificate = "Certificate"
            case endpointDetails = "EndpointDetails"
            case endpointType = "EndpointType"
            case hostKey = "HostKey"
            case identityProviderDetails = "IdentityProviderDetails"
            case loggingRole = "LoggingRole"
            case protocols = "Protocols"
            case securityPolicyName = "SecurityPolicyName"
            case serverId = "ServerId"
        }
    }

    public struct UpdateServerResponse: AWSDecodableShape {
        /// A system-assigned unique identifier for a server that the user account is assigned to.
        public let serverId: String

        public init(serverId: String) {
            self.serverId = serverId
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
        }
    }

    public struct UpdateUserRequest: AWSEncodableShape {
        /// Specifies the landing directory (folder) for a user when they log in to the server using their file transfer protocol client. An example is your-Amazon-S3-bucket-name&gt;/home/username.
        public let homeDirectory: String?
        /// Logical directory mappings that specify what Amazon S3 paths and keys should be visible to your user and how you want to make them visible. You will need to specify the "Entry" and "Target" pair, where Entry shows how the path is made visible and Target is the actual Amazon S3 path. If you only specify a target, it will be displayed as is. You will need to also make sure that your IAM role provides access to paths in Target. The following is an example.  '[ "/bucket2/documentation", { "Entry": "your-personal-report.pdf", "Target": "/bucket3/customized-reports/${transfer:UserName}.pdf" } ]'  In most cases, you can use this value instead of the scope-down policy to lock your user down to the designated home directory ("chroot"). To do this, you can set Entry to '/' and set Target to the HomeDirectory parameter value.  If the target of a logical directory entry does not exist in Amazon S3, the entry will be ignored. As a workaround, you can use the Amazon S3 API to create 0 byte objects as place holders for your directory. If using the CLI, use the s3api call instead of s3 so you can use the put-object operation. For example, you use the following: aws s3api put-object --bucket bucketname --key path/to/folder/. Make sure that the end of the key name ends in a / for it to be considered a folder.
        public let homeDirectoryMappings: [HomeDirectoryMapEntry]?
        /// The type of landing directory (folder) you want your users' home directory to be when they log into the server. If you set it to PATH, the user will see the absolute Amazon S3 bucket paths as is in their file transfer protocol clients. If you set it LOGICAL, you will need to provide mappings in the HomeDirectoryMappings for how you want to make Amazon S3 paths visible to your users.
        public let homeDirectoryType: HomeDirectoryType?
        /// Allows you to supply a scope-down policy for your user so you can use the same IAM role across multiple users. The policy scopes down user access to portions of your Amazon S3 bucket. Variables you can use inside this policy include ${Transfer:UserName}, ${Transfer:HomeDirectory}, and ${Transfer:HomeBucket}.  For scope-down policies, AWS Transfer Family stores the policy as a JSON blob, instead of the Amazon Resource Name (ARN) of the policy. You save the policy as a JSON blob and pass it in the Policy argument. For an example of a scope-down policy, see Creating a scope-down policy. For more information, see AssumeRole in the AWS Security Token Service API Reference.
        public let policy: String?
        public let posixProfile: PosixProfile?
        /// The IAM role that controls your users' access to your Amazon S3 bucket. The policies attached to this role will determine the level of access you want to provide your users when transferring files into and out of your Amazon S3 bucket or buckets. The IAM role should also contain a trust relationship that allows the server to access your resources when servicing your users' transfer requests.
        public let role: String?
        /// A system-assigned unique identifier for a server instance that the user account is assigned to.
        public let serverId: String
        /// A unique string that identifies a user and is associated with a server as specified by the ServerId. This user name must be a minimum of 3 and a maximum of 100 characters long. The following are valid characters: a-z, A-Z, 0-9, underscore '_', hyphen '-', period '.', and at sign '@'. The user name can't start with a hyphen, period, or at sign.
        public let userName: String

        public init(homeDirectory: String? = nil, homeDirectoryMappings: [HomeDirectoryMapEntry]? = nil, homeDirectoryType: HomeDirectoryType? = nil, policy: String? = nil, posixProfile: PosixProfile? = nil, role: String? = nil, serverId: String, userName: String) {
            self.homeDirectory = homeDirectory
            self.homeDirectoryMappings = homeDirectoryMappings
            self.homeDirectoryType = homeDirectoryType
            self.policy = policy
            self.posixProfile = posixProfile
            self.role = role
            self.serverId = serverId
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.homeDirectory, name: "homeDirectory", parent: name, max: 1024)
            try self.validate(self.homeDirectory, name: "homeDirectory", parent: name, pattern: "^$|/.*")
            try self.homeDirectoryMappings?.forEach {
                try $0.validate(name: "\(name).homeDirectoryMappings[]")
            }
            try self.validate(self.homeDirectoryMappings, name: "homeDirectoryMappings", parent: name, max: 50)
            try self.validate(self.homeDirectoryMappings, name: "homeDirectoryMappings", parent: name, min: 1)
            try self.validate(self.policy, name: "policy", parent: name, max: 2048)
            try self.posixProfile?.validate(name: "\(name).posixProfile")
            try self.validate(self.role, name: "role", parent: name, max: 2048)
            try self.validate(self.role, name: "role", parent: name, min: 20)
            try self.validate(self.role, name: "role", parent: name, pattern: "arn:.*role/.*")
            try self.validate(self.serverId, name: "serverId", parent: name, max: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, min: 19)
            try self.validate(self.serverId, name: "serverId", parent: name, pattern: "^s-([0-9a-f]{17})$")
            try self.validate(self.userName, name: "userName", parent: name, max: 100)
            try self.validate(self.userName, name: "userName", parent: name, min: 3)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[\\w][\\w@.-]{2,99}$")
        }

        private enum CodingKeys: String, CodingKey {
            case homeDirectory = "HomeDirectory"
            case homeDirectoryMappings = "HomeDirectoryMappings"
            case homeDirectoryType = "HomeDirectoryType"
            case policy = "Policy"
            case posixProfile = "PosixProfile"
            case role = "Role"
            case serverId = "ServerId"
            case userName = "UserName"
        }
    }

    public struct UpdateUserResponse: AWSDecodableShape {
        /// A system-assigned unique identifier for a server instance that the user account is assigned to.
        public let serverId: String
        /// The unique identifier for a user that is assigned to a server instance that was specified in the request.
        public let userName: String

        public init(serverId: String, userName: String) {
            self.serverId = serverId
            self.userName = userName
        }

        private enum CodingKeys: String, CodingKey {
            case serverId = "ServerId"
            case userName = "UserName"
        }
    }
}
